package main

import (
	"fmt"
	"reflect"
	"time"
	"unsafe"
)

func getSliceInfo(A interface{}) {
	sh := (*reflect.SliceHeader)(unsafe.Pointer(&A))
	fmt.Printf("A Data:%d,Len:%d,Cap:%d\n", sh.Data, sh.Len, sh.Cap)
}

func main() {
	fmt.Println("alloc begin!")
	for i := 0; i < GlobalMemAllocTimes; i++ {
		time.Sleep(time.Second * 1)
		memAlloc()
		// memAllocWithNotPointer()
		sh := (*reflect.SliceHeader)(unsafe.Pointer(&GlobalMemPoolNotPointer))
		fmt.Printf("A Data:%d,Len:%d,Cap:%d\n", sh.Data, sh.Len, sh.Cap)
		//getSliceInfo(GlobalMemPoolNotPointer)
	}
}

const (
	// MillionSize is 1M
	MillionSize = 1 << 20
)

type stMem struct {
	body [8 * MillionSize]byte
}
// GlobalMemAllocTimes is the alloc times
const GlobalMemAllocTimes = 20

// GlobalMemPool is a pool of mem alloc
var GlobalMemPool [GlobalMemAllocTimes]*stMem


// GlobalMemCnt is the cnt of mem alloc
var GlobalMemCnt uint64

var isInit bool

//
func lazyInit() {
	if isInit {
		return
	}
	isInit = true
	GlobalMemPool = make([]*stMem, 0)
	GlobalMemCnt = 0
}

// GlobalMemPoolNotPointer is global var
var GlobalMemPoolNotPointer []stMem

// GlobalMemPoolNotPointerCnt is cnt
var GlobalMemPoolNotPointerCnt uint64

func memAllocWithNotPointer() {
	st := stMem{}
	GlobalMemPoolNotPointer[GlobalMemPoolNotPointerCnt] = st
	// GlobalMemPoolNotPointer = append(GlobalMemPoolNotPointer, st)
	GlobalMemPoolNotPointerCnt++
	fmt.Printf("[alloc] mem cnt: [%v]\n", GlobalMemPoolNotPointerCnt)
}

func memAlloc() {
	st := stMem{}
	GlobalMemPool[GlobalMemCnt] = &st
	GlobalMemCnt++
	fmt.Printf("[alloc] mem cnt: [%v]\n", GlobalMemCnt)
}
